package fr.afcepf.atod18.utilitaires;

import java.io.IOException; //pour les erreurs de lecture du fichier
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder; //pour l’ouverture et la construction du DOM
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import fr.afcepf.atod18.frwk.entities.Action;
import fr.afcepf.atod18.frwk.entities.Form;

public class ParserXml {
	// public static void main(String[] args) throws
	// ParserConfigurationException,
	// SAXException, IOException {
	// // TODO Auto-generated method stub
	// String fichier = "./paramFWK.xml";
	// /* 1 */
	// System.out.println("chargement du fichier " + fichier);
	// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	// DocumentBuilder builder = factory.newDocumentBuilder();
	// /* 2 */
	// Document document = builder.parse(fichier);
	// /* 3 */
	// Element racine = document.getDocumentElement();
	// NodeList actions = racine.getElementsByTagName("action");
	// System.out.println("Liste des actions contient : "
	// + actions.getLength());
	//
	// /* 4 */// parcours des actions
	// for (int i = 0; i < actions.getLength(); i++) {
	// Node uneAction = actions.item(i);
	// // elements action
	// NodeList elements = uneAction.getChildNodes();
	// for (int j = 0; j < elements.getLength(); j++) {
	// Node enfant = elements.item(j);
	// if (enfant.getNodeName().equals("action-name"))
	// System.out
	// .println("action-name " + enfant.getTextContent());
	// if (enfant.getNodeName().equals("url-pattern"))
	// System.out
	// .println("url-pattern " + enfant.getTextContent());
	// if (enfant.getNodeName().equals("form-name"))
	// System.out.println("form-name " + enfant.getTextContent());
	// }
	// }
	//
	// NodeList forms = racine.getElementsByTagName("form");
	//
	// /* 4 */// parcours des forms
	// for (int i = 0; i < forms.getLength(); i++) {
	// Node uneForm = forms.item(i);
	// // elements form
	// NodeList elementsNode = uneForm.getChildNodes();
	// for (int j = 0; j < elementsNode.getLength(); j++) {
	// Node enfantForm = elementsNode.item(j);
	// if (enfantForm.getNodeName().equals("form-class"))
	// System.out.println("form-class "
	// + enfantForm.getTextContent());
	// if (enfantForm.getNodeName().equals("form-name"))
	// System.out.println("form-name "
	// + enfantForm.getTextContent());
	// }
	// }
	//
	// }
	public static void main(String[] args) throws ParserConfigurationException,
			SAXException, IOException {
		Action a = new Action();
		Form f = new Form();

		List<Object> lTags = new ArrayList<Object>();
		lTags.add(a);
		lTags.add(f);

		List<Map<String, Object>> resu;
		resu = parse("./paramFWK.xml", lTags);

		if (resu != null) {
			System.out.println("nombre de Map retournées " + resu.size());
			for (int i = 0; i < resu.size(); i++) {
				Map<String, Object> map = resu.get(i);
				System.out.println("Map " + i + " contient" + map.size()
						+ " elements");
				System.out.println(map.toString()); 
				Collection<Object> coll = map.values();
				List<Object> tempList = new ArrayList<Object>(coll);
				for (int j = 0; j < tempList.size(); j++){
					Object o = tempList.get(j);
					System.out.println(i + "emme elt de type "+ o.getClass().getSimpleName());
					System.out.println(o.toString());
				}
				System.out.println(coll.toString()); 
				
			}
		}

	}

	public static List<Map<String, Object>> parse(String nomFic,
			List<Object> listeTag) throws ParserConfigurationException,
			SAXException, IOException {

		List<Map<String, Object>> ListeMaps = new ArrayList<Map<String, Object>>();

		/* 1 */
		System.out.println("chargement du fichier " + nomFic);
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		/* 2 */
		Document document = builder.parse(nomFic);
		/* 3 */
		Element racine = document.getDocumentElement();

		if ((listeTag == null) || (listeTag.size() == 0)) {
			return null;
		}
		System.out.println("Nbre de tags à traiter " + listeTag.size());

		for (int i = 0; i < listeTag.size(); i++) {
			// boucle sur la liste des tags à mapper
			Object o = listeTag.get(i);
			Class c = o.getClass();

			System.out.println("creation Map n° " + i);
			Map<String, Object> theMap = new HashMap<String, Object>();

			NodeList eltsTags = racine.getElementsByTagName(c.getSimpleName()
					.toLowerCase()); // recup ds fic xml des struct du tag
			System.out.println("Liste eltstags contient : "
					+ eltsTags.getLength() + " " + c.getSimpleName());
			/* 4 */// parcours des actions
			for (int j = 0; j < eltsTags.getLength(); j++) {
				try {
					Object obj = c.newInstance();
					Node unTagTrt = eltsTags.item(j);
					// elements action
					NodeList elements = unTagTrt.getChildNodes();
					String cleMap = new String();
					for (int k = 0; k < elements.getLength(); k++) {
						Node enfant = elements.item(k);
						Field[] listAtrributs = c.getDeclaredFields();
						for (int z = 0; z < listAtrributs.length; z++) {
							if (enfant.getNodeName().equals(
									listAtrributs[z].getName()
											.replace("_", "-"))) {
								if (z == 0) {
									cleMap = enfant.getTextContent();
									System.out.println("cleMap = "+ cleMap + "z = "+z);
								}

								String nomChamp = listAtrributs[z].getName();
								nomChamp = nomChamp.substring(0, 1)
										.toUpperCase() + nomChamp.substring(1);
								try {
									Method m = c.getMethod("set" + nomChamp,
											listAtrributs[z].getType());
									try {
										m.invoke(obj, enfant.getTextContent());
									} catch (IllegalArgumentException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									} catch (InvocationTargetException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
								} catch (NoSuchMethodException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (SecurityException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (DOMException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
//								System.out.println(listAtrributs[z].getName()
//										+ " : " + enfant.getTextContent());
								break;
							}
						}
					}
					theMap.put(cleMap, obj);
					System.out.println(j + "eme ajout dans la map");

				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			ListeMaps.add(theMap);
			System.out.println(i + "eme ajout dans la liste de maps");
		}
		return ListeMaps;
	}

}
